<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\cdc\cost\pull;

use app\enum\CommonEnum;
use app\enum\OceanEnum;
use app\enum\ServiceCostEnum;
use app\model\CostTaskAccountModel;
use app\service\BaseService;
use app\service\cdc\cost\TaskNoticeService;
use app\service\client\AccountService;
use app\service\ocean\AdvertiserService;
use app\service\ocean\FinanceService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class OceanService extends BaseService implements PullInterface
{
    private array $params = [];

    /**
     * @var bool|mixed|string
     */
    private array $response = [];

    private array $thisResponseData = [];

    private array $responseData = [];

    /**
     * 判断服务.
     */
    public function isResponseSuccess(): bool
    {
        return FinanceService::isResponseSuccess($this->getResponseCode());
    }

    /**
     * @return bool 请求数据是否为空
     */
    public function isResponseEmpty(): bool
    {
        return empty($this->thisResponseData);
    }

    /**
     * 获取请求头部.
     * @return array|bool
     */
    public function getHeader(string $token = '')
    {
        return FinanceService::getHeader($token);
    }

    /**
     * 获取返回码.
     * @return mixed
     */
    public function getResponseCode()
    {
        return $this->response['code'] ?? '-10000';
    }

    /**
     * 获取返回错误信息.
     * @return mixed
     */
    public function getResponseMsg()
    {
        return $this->response['message'] ?? '';
    }

    /**
     * 获取返回体.
     */
    public function getResponseData(array $args = []): array
    {
        return $this->responseData;
    }

    /**
     * 获取媒体.
     */
    public function getMediaId(): int
    {
        return CommonEnum::OE_MEDIA;
    }

    /**
     * 获取账户流水.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAdvertiserDailyFlow(CostTaskAccountModel $model): bool
    {
        // token:barrel:1:4
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }
        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => OceanEnum::MAX_PAGE_SIZE,
        ];
        $this->response = FinanceService::getAdvertiserDailyFlow($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }

        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取账户视频报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialDailyReport(CostTaskAccountModel $model): bool
    {
        // token:barrel:1:4
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'group_by' => ['STAT_GROUP_BY_TIME_DAY', 'STAT_GROUP_BY_MATERIAL_ID'],
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => OceanEnum::MAX_MATERIAL_PAGE_SIZE,
            'fields' => OceanEnum::VIDEO_REPORT_FIELD,
        ];
        $this->response = FinanceService::getMaterialDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'list');
        // 体验版
        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'],
            'start_time' => $this->params['start_date'],
            'end_time' => $this->params['start_date'],
            'page' => $this->params['page'],
            'page_size' => OceanEnum::MAX_CUSTOM_MATERIAL_PAGE_SIZE,
            'data_topic' => 'MATERIAL_DATA',
            'metrics' => OceanEnum::VIDEO_CUS_REPORT_FIELD,
            'dimensions' => ['image_mode', 'material_id', 'stat_time_day'],
            'filters' => [['field' => 'stat_cost', 'type' => 3, 'operator' => 4, 'values' => ['0' => '0']]],
            'order_by' => [['field' => 'material_id']],
        ];
        $this->response = FinanceService::getCustomMaterialDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        if (isset($this->response['data'])) {
            $this->thisResponseData = array_merge(filterData($this->response['data'], 'rows'), $this->thisResponseData);
            $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        }
        return true;
    }

    /**
     * 获取体验版账户视频报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getCustomMaterialDailyReport(CostTaskAccountModel $model): bool
    {
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_time' => $this->params['start_time'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_time' => $this->params['start_time'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => OceanEnum::MAX_CUSTOM_MATERIAL_PAGE_SIZE,
            'data_topic' => 'MATERIAL_DATA',
            'metrics' => OceanEnum::VIDEO_CUS_REPORT_FIELD,
            'dimensions' => ['image_mode', 'material_id', 'stat_time_day'],
            'filters' => [['field' => 'stat_cost', 'type' => 3, 'operator' => 4, 'values' => ['0' => '0']]],
            'order_by' => [['field' => 'material_id']],
        ];
        $this->response = FinanceService::getCustomMaterialDailyReport($headers, $this->params);
        $this->thisResponseData = filterData($this->response['data'], 'rows');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取账户图片报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialPicDailyReport(CostTaskAccountModel $model): bool
    {
        // token:barrel:1:4
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }
        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => OceanEnum::MAX_MATERIAL_PAGE_SIZE,
            'group_by' => ['STAT_GROUP_BY_MATERIAL_ID', 'STAT_GROUP_BY_TIME_DAY'],
            'filtering' => OceanEnum::PIC_REPORT_FILTERING,
        ];
        $this->response = FinanceService::getMaterialIntegratedDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'list');
        // 体验版
        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'],
            'start_time' => $this->params['start_date'],
            'end_time' => $this->params['start_date'],
            'page' => $this->params['page'],
            'page_size' => OceanEnum::MAX_CUSTOM_MATERIAL_PAGE_SIZE,
            'data_topic' => 'MATERIAL_DATA',
            'metrics' => OceanEnum::VIDEO_CUS_REPORT_FIELD,
            'dimensions' => ['image_mode', 'material_id', 'stat_time_day'],
            'filters' => [['field' => 'stat_cost', 'type' => 3, 'operator' => 4, 'values' => ['0' => '0']]],
            'order_by' => [['field' => 'material_id']],
        ];
        $this->response = FinanceService::getCustomMaterialDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        if (isset($this->response['data'])) {
            $this->thisResponseData = array_merge(filterData($this->response['data'], 'rows'), $this->thisResponseData);
            $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        }
        return true;
    }

    public function getVideoList(CostTaskAccountModel $model, string $materialId = ''): bool
    {
        // token:barrel:1:4
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $response = AdvertiserService::getVideoList($headers, [
            'advertiser_id' => $model->getAttr('advertiser_id'),
            'page' => 1,
            'page_size' => OceanEnum::MAX_CUSTOM_MATERIAL_PAGE_SIZE,
            'filtering' => [
                'material_ids' => [$materialId],
            ],
        ]) ?? [];

        $this->response = is_bool($response) ? [] : $response;
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'list');

        if (isset($this->response['data'])) {
            $this->thisResponseData = array_merge(filterData($this->response['data'], 'rows'), $this->thisResponseData);
            $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        }

        return true;
    }

    /**
     * 获取报表信息.
     */
    public function getAccountReportList(CostTaskAccountModel $model): bool
    {
        // token:barrel:1:4
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => OceanEnum::MAX_PAGE_SIZE,
        ];
        $this->response = FinanceService::getAdvertiserReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }

        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }
}
